package de.eves.rocksongs;

import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import de.eves.hibernate.InitSessionFactory;

public class RockSongsTest {
	private static Logger log = Logger.getLogger(RockSongsTest.class);

	private static Band createBand(String name) {
		Band newBand = new Band();
		newBand.setName(name);
		Session session = InitSessionFactory.getInstance().getCurrentSession();
		Transaction tx = session.beginTransaction();
		session.save(newBand);
		tx.commit();
		return newBand;
	}

	private static Musician createMusician(String name, String role, String band) {
		boolean found = false;
		Musician newMusician = new Musician();
		newMusician.setName(name);
		newMusician.setRole(role);
		Session session = InitSessionFactory.getInstance().getCurrentSession();
		Transaction tx = session.beginTransaction();
		session.save(newMusician);
		tx.commit();
		return newMusician;
	}

	private static Song createSong(String name, String type, String band) {
		Song newSong = new Song();
		newSong.setName(name);
		newSong.setType(type);
		Session session = InitSessionFactory.getInstance().getCurrentSession();
		Transaction tx = session.beginTransaction();
		session.save(newSong);
		tx.commit();
		session = InitSessionFactory.getInstance().getCurrentSession();
		tx = session.beginTransaction();
		String hql = "from Band b where b.name = :name";
		Band newBand = (Band) session.createQuery(hql)
				.setParameter("name", band).uniqueResult();
		System.out.println(newBand.getName());
		if (newBand != null) {
			newBand.getSongs().add(newSong);
			newSong.setBand(newBand);
		}
		// session.merge(newSong);
		session.merge(newBand);
		tx.commit();
		// update(newBand);
		return newSong;
	}

	private static void update(Band band) {
		Session session = InitSessionFactory.getInstance().getCurrentSession();
		Transaction tx = session.beginTransaction();
		session.update(band);
		tx.commit();
	}

	private static void update(Musician musician) {
		Session session = InitSessionFactory.getInstance().getCurrentSession();
		Transaction tx = session.beginTransaction();
		session.update(musician);
		tx.commit();
	}

	private static void update(Song song) {
		Session session = InitSessionFactory.getInstance().getCurrentSession();
		Transaction tx = session.beginTransaction();
		session.update(song);
		tx.commit();
	}

	private static void delete(Band band) {
		Transaction tx = null;
		Session session = InitSessionFactory.getInstance().getCurrentSession();
		tx = session.beginTransaction();
		session.delete(band);
		tx.commit();
	}

	private static void delete(Song song) {
		Transaction tx = null;
		Session session = InitSessionFactory.getInstance().getCurrentSession();
		tx = session.beginTransaction();
		session.delete(song);
		tx.commit();
	}

	private static void delete(Musician musician) {
		Transaction tx = null;
		Session session = InitSessionFactory.getInstance().getCurrentSession();
		tx = session.beginTransaction();
		session.delete(musician);
		tx.commit();
	}

	private static void clean() {
		Session session = InitSessionFactory.getInstance().getCurrentSession();
		Transaction tx = session.beginTransaction();
		session.createQuery("delete from Band").executeUpdate();
		session.createQuery("delete from Song").executeUpdate();
		session.createQuery("delete from Musician").executeUpdate();
		session.flush();
		session.clear();
		tx.commit();
	}

	private static void createRelation(Band band, Song song) {
		Session session = InitSessionFactory.getInstance().getCurrentSession();
		Transaction tx = session.beginTransaction();

		/* Wir setzen die Beziehung auf BEIDEN Seiten */
		song.setBand(band);
		band.getSongs().add(song);
		tx.commit();
	}

	private static void createRelation(Band band, Musician musician) {
		Session session = InitSessionFactory.getInstance().getCurrentSession();
		Transaction tx = session.beginTransaction();

		/* Wir setzen die Beziehung auf BEIDEN Seiten */
		musician.setBand(band);
		band.getMembers().add(musician);
		tx.commit();
	}

	public static void main(String[] args) {
		try {
			Band band;
			Song song;
			Musician musician;
			clean();

			// Band band2 = createBand("Linkin Park");
			// Session s = InitSessionFactory.getInstance().getCurrentSession();
			// Transaction tx2 = s.beginTransaction();
			// s.merge(band2);
			// Song song2 = new Song("Alle meine Entcsdfsdfasd");
			// s.save(song2);
			// band2.getSongs().add(song2);
			// s.save(band2);
			// tx2.commit();
			createBand("Linkin Park");
			createBand("Scorpions");
			createSong("Numb", "NU Metal", "Linkin Park");
			createSong("Wind of change", "Ballard", "Scorpions");
			createSong("In the end", "NU Metal", "Linkin Park");
			createMusician("Klaus Meine", "Vocal", "Scorpions");
			createMusician("Rudolf Schenker", "Guitarist", "Scorpions");
			createMusician("Chester Bennington", "Vocal", "Linkin Park");
			createMusician("Mike Shinoda", "Vocal", "Linkin Park");

			Session session = InitSessionFactory.getInstance()
					.getCurrentSession();
			Transaction tx = session.beginTransaction();

			band = (Band) session.get(Band.class, new Integer("1"));
			System.out.println(band.getName() + ", have " + band.getSongs());
			tx.commit();

		} catch (RuntimeException e) {
			try {
				Session session = InitSessionFactory.getInstance()
						.getCurrentSession();
				if (session.getTransaction().isActive())
					session.getTransaction().rollback();
			} catch (HibernateException e1) {
				log.error("Error rolling back transaction");
			}
			// throw the exception again
			throw e;
		}
	}
}
